package networkSimulation.simulation.virus

import util.Random
import networkSimulation.framework.{Graph, Edge, Node}

/**
 * This class represents a Node that can be infected by a virus.
 *
 * @author  Tim Caljé
 *          Jeroen De Raedt
 *          Jorick Van Aken
 */
class InfectablePerson(name: String, var infected: Boolean, var immune: Boolean, var isDead: Boolean, var nbDaysOfInfection: Int) extends Node(name) {

  /**
   *  The number of turns this node can survive while infected.
   */
  def getSurvivalDays() = 4

  /**
   *  Alternate constructors
   */
  def this(name : String, infected : Boolean, immune : Boolean) = this(name, infected, immune, false, 0)
  def this(name: String) = this(name, false, false)
  def this(name: String, immune : Boolean) = this(name, false, immune)

  /**
   * Increment the amount of days that this person has been infected
   */
  private def incrementNbDaysOfInfection() {
    nbDaysOfInfection += 1
    if (nbDaysOfInfection >= this.getSurvivalDays())
      die
  }

  /**
   * Let this person die
   */
  def die {
    this.infected = false
    this.isDead = true
    this.publish()
  }

  /**
   * Custom Simulation method
   */
  @Override
  override def simulate[N<%Node, E<%Edge[N]](graph: Graph[N, E]) {
    for(node: InfectablePerson <- graph.getNeighbours(this.asInstanceOf[N]).map(_.asInstanceOf[InfectablePerson]).toList if node.infected && !this.infected && !this.immune) {
      val rand = new Random().nextInt(2)  // 50% chance on infection
      if(rand == 1) {
        this.infected = true        
      }
    }
    if (this.infected) {
      this.incrementNbDaysOfInfection()
    }
  }

  /**
   * Define the color of this node (for the visualisation)
   */
  @Override
  override def getColor() : String = {
    if (isDead)   return "black"
    if (immune)   return "blue"
    if (infected) return "red"
    else          return "green"
  }

}